import EventBus from '../utils/eventbus'
import {
    EventDispatcher,
    Object3D,
    Vector3
} from 'three'

export const overlaySymbol = Symbol('overlay');

abstract class Overlay extends EventDispatcher {
    private _uuid: number | string;
    private _children: Overlay[] = [];
    private _parent: Overlay = null;
    private _zIndex = 0;
    private __eventbus = new EventBus();

    public abstract getObject(): Object3D

    protected get isMap() {
        return false
    }

    public get uuid() {
        return this._uuid
    }

    public set uuid(id: number | string) {
        this._uuid = id
    }

    public get children() {
        return this._children
    }

    public get parent() {
        return this._parent
    }

    public get zIndex(): number {
        return this._zIndex
    }

    public set zIndex(value: number) {
        this._zIndex = value || 0
    }

    public add(overlay: Overlay) {
        this.children.push(overlay);
        overlay._parent = this;
        let object = overlay.getObject();
        this.getObject().add(object);
        // @ts-ignore
        object[overlaySymbol] = overlay
    }

    remove(overlay: Overlay) {
        let object = overlay.getObject();
        // @ts-ignore
        delete object[overlaySymbol];
        this.getObject().remove(object);
        overlay._parent = null;
        let children = this.children;
        let index = children.lastIndexOf(overlay);
        children.splice(index, 1);
    }

    dispatchEvent(event: { type: string; [attachment: string]: any }): void {
        super.dispatchEvent(event);
        if (this.parent && event.bubbled) {
            this.parent.dispatchEvent(event);
        }
    }

    public setVisible(visible: boolean) {
        this.getObject().visible = visible
    }

    public getPosition(): Vector3 {
        return this.getObject().position
    }

    public getMap() {
        let target: Overlay = this;
        while (!(target.isMap)) {
            target = target.parent;
            if (target === null) {
                break
            }
        }
        return target
    }
}

export default Overlay
